;************************************* ;*Project title: PIC Day Indicator * ;*Version 1: 1.0 * ;*Written By: MSH * ;*Dated: 06/01/07 * ;*For PIC: PIC16F84A * ;*Clock Freq: 8.0MHz * ;************************************* ; PROGRAM FUNCTION:___________________________ ;_____________________________________________ List P=16F84A include ;============ ; Declarations: porta equ 05 portb equ 06 serial_data equ 0C bit_count equ 0D post100 equ 0E hex_value equ 0F mark192 equ 10 post15 equ 11 post244 equ 12 tod equ 13 address equ 14 day_time equ 15 dark_time equ 16 last_time equ 17 LEDSTATE equ 18 TMR0_save equ 19 post50 equ 1A mark64 equ 1B #define clk porta,2 #define dout porta,3 #define cs porta,4 org 0 goto Start ;============ ; Subroutines: Init clrf porta ; resets Port A and B. clrf portb ; bsf STATUS,5 ; selects bank 1 movlw b'01011' ; RA0-RA1 = LEDs 1 & 2, RA2 = ADC_CLK, movwf TRISA ; RA3 = ADC_Dout, RA4 = ADC_CS. movlw b'00000000' ; RB0-RB7 = LEDs 3-7. movwf TRISB ; the LEDs. movlw b'00000111' ; TMR0 prescaled by 256 movwf OPTION_REG ; pull ups disabled. movlw b'00000100' ; movwf EECON1 ; bcf STATUS, 5 ; Selects bank 0 bsf cs ; disables adc chip (U2). call resetpost100 ; resets post100. call resetpost15 ; resets post15. call resetpost50 ; resets post50. call resetmark64 ; resets mark64. call resetmark192 ; resets mark192. call resetpost244 ; resets post244. clrf tod ; clrf address ; clrf LEDSTATE ; clrf hex_value ; clrf serial_data ; clrf dark_time ; clrf day_time ; clrf EEADR ; clrf TMR0_save ; bcf last_time,0 ; bsf last_time,1 ; movlw b'00000000' ; disables all interrupts. movwf INTCON ; return ; returns from subroutine. adc_dataout bcf cs ; enables adc chip (U2). clrf serial_data ; Clears file for storing the ADC's 8bit output. movlw d'8' ; places the decimal No '8' into the file movwf bit_count ; register bit_count. loop btfsc dout ; is the bit on ADC D_out pin a 0. bsf STATUS,C ; if no sets carry flag. btfss dout ; is the bit on ADC D-out pin a 1. bcf STATUS,C ; if yes clears carry flag. bsf clk ; creates a high clock on the ADC clk pin. nop ; creates a 1/2000000th of a second delay. bcf clk ; creates a low clock on the ADC clk pin. rlf serial_data,f ; places contents of the carry flag into serial_data. decfsz bit_count,f ; have all 8 bits been recieved. goto loop return ; returns from subroutine. bin2hex movlw h'00' ; clears contents of working reg. btfsc serial_data,7 ; tests bit 7 of file register serial_data. addlw h'80' ; adds the hexidecimal No'7F' to working reg. btfsc serial_data,6 ; tests bit 6 of file register serial_data. addlw h'40' ; adds the hexidecimal No'3F' to working reg. btfsc serial_data,5 ; tests bit 5 of file register serial_data. addlw h'20' ; adds the hexidecimal No'1F' to working reg. btfsc serial_data,4 ; tests bit 4 of file register serial_data. addlw h'10' ; adds the hexidecimal No'0F' to working reg. btfsc serial_data,3 ; tests bit 3 of file register serial_data. addlw h'08' ; adds the hexidecimal No'08' to working reg. btfsc serial_data,2 ; tests bit 2 of file register serial_data. addlw h'04' ; adds the hexidecimal No'04' to working reg. btfsc serial_data,1 ; tests bit 1 of file register serial_data. addlw h'02' ; adds the hexidecimal No'02' to working reg. btfsc serial_data,0 ; tests bit 0 of file register serial_data. addlw h'01' ; adds the hexidecimal No'01' to working reg. movwf hex_value ; moves value in working reg into file ; register 'hex_value'. return ; returns from subroutine. decode btfss serial_data,7 ; goto bit7c ; goto bit7s ; bit7c btfss serial_data,6 ; goto bit7c6c ; goto bit7c6s ; bit7s bsf tod,0 ; light level indicates daytime. return ; returns from subroutine. bit7c6c btfss serial_data,5 ; goto bit5c ; goto bit5s ; bit7c6s bsf tod,1 ; light level indicates nighttime. return ; returns from subroutine. bit5c bsf tod,2 ; light level indicates Dark. return ; returns from subroutine. bit5s bsf tod,1 ; return ; returns from subroutine. store_bit bcf STATUS,5 ; movf hex_value,w ; movwf EEDATA ; movf address,w ; movwf EEADR ; bsf STATUS,5 ; movlw H'55' ; movwf EECON2 ; movlw H'AA' ; movwf EECON2 ; bsf EECON1,1 ; starts write operation. EELoop1 btfsc EECON1,1 ; test the write complete bit goto EELoop1 ; bit still high, so keeps looping. bcf STATUS,5 ; movlw h'01' ; addwf address,f ; return ; returns from subroutine. read_bit bcf STATUS,5 ; selects bank 0 movf address,w ; movwf EEADR ; bsf STATUS,5 ; bsf EECON1,0 ; bcf STATUS,5 ; movfw EEDATA ; movwf serial_data ; call decode ; btfss tod,0 ; goto Tod2 ; incf day_time,f ; Tod2 btfss tod,2 ; goto next ; incf dark_time,f ; next clrf tod ; clears tod file register. incf address,f ; return ; returns from subroutine. which_LED addwf PCL,f ; retlw b'00000000' ; retlw b'10000000' ; retlw b'01000000' ; retlw b'00100000' ; retlw b'00010000' ; retlw b'00001000' ; retlw b'00000100' ; retlw b'00000010' ; resetpost100 movlw d'100' ; moves the decimal number '100' into the movwf post100 ; files register post100. return ; returns from subroutine. resetpost15 movlw d'15' ; moves the decimal number '15' into the movwf post15 ; files register post15. return ; returns from subroutine. resetpost50 movlw d'50' ; moves the decimal number '50' into the movwf post50 ; files register post50. return ; returns from subroutine. resetpost244 movlw d'244' ; moves the decimal number '244' into the movwf post244 ; files register post244. return ; returns from subroutine. resetmark64 movlw d'64' ; moves the decimal number '64' into the movwf mark64 ; files register post64. return ; returns from subroutine. resetmark192 movlw d'192' ; moves the decimal number '192' into the movwf mark192 ; files register post192. return ; returns from subroutine. timer clrf TMR0 ; resets TMR0. timer1 movfw mark192 ; tests to see if TMR0 has reached 192 subwf TMR0,w ; incremented through 192 cycles. btfss STATUS,Z ; tests the zero flag - skips if set. goto timer1 ; loops to timer1. decfsz post244,f ; goto timer ; loops to timer. call resetpost244 ; resets post244. decfsz post100,f ; goto timer ; call resetpost100 ; resets resetpost100. return ; returns from subroutine. T_Delay clrf TMR0 ; T_Delay1 movlw mark64 ; subwf TMR0,w ; btfss STATUS,Z ; goto T_Delay1 ; decfsz post50,f ; goto T_Delay ; call resetpost50 ; resets post50. return ; returns from subroutine. ;============================================ ; Program Start: Start call Init ; sets up everything. main btfsc porta,0 ; goto main01 ; btfss porta,1 ; goto main ; incf LEDSTATE,f ; movfw LEDSTATE ; takes number out of LEDSTATE. call which_LED ; movwf portb ; turns on relavent LED. call T_Delay ; creates a time delay. movlw d'07' ; subwf LEDSTATE,w ; btfss STATUS,Z ; goto continue1 ; clrf LEDSTATE ; continue1 goto main ; main01 call adc_dataout ; movfw serial_data ; call bin2hex ; creates a hexidecimal value from serial data. call store_bit ; call timer ; decfsz post15,f ; goto main01 ; call resetpost15 ; clrf address ; read call read_bit ; decfsz post15,f ; goto read ; call resetpost15 ; movlw d'15' ; subwf day_time,w ; btfss STATUS,Z ; goto night ; btfss last_time,0 ; goto continue2 ; bsf last_time,1 ; bcf last_time,0 ; night movlw d'15' ; subwf dark_time,w ; btfss STATUS,Z ; goto continue2 ; btfss last_time,1 ; goto continue2 ; bsf last_time,0 ; bcf last_time,1 ; incf LEDSTATE,f ; movfw LEDSTATE ; takes number out of LEDSTATE. call which_LED ; movwf portb ; turns on relavent LED. movlw d'07' ; subwf LEDSTATE,w ; btfss STATUS,Z ; goto continue2 ; clrf LEDSTATE ; continue2 clrf day_time ; clrf dark_time ; clrf address ; goto main01 ; loops to main. END ; Appendix A: LED Allocation. ; ; ;==================================================== ;8 bit coversion. ; ;CALL LED1 = 0 - 13 00000000 - 00001101 ;CALL LED1A = 13 - 26 00001101 - 00011010 ;CALL LED2 = 26 - 39 00011010 - 00100111 ;CALL LED2A = 39 - 52 00100111 - 00110100 ;CALL LED3 = 52 - 65 00110100 - 01000001 ;CALL LED3A = 65 - 78 01000001 - 01001110 ;CALL LED4 = 78 - 91 01001110 - 01011011 ;CALL LED4A = 91 - 104 01011011 - 01101000 ;CALL LED5 = 104 - 117 01101000 - 01110101 ;CALL LED5A = 117 - 130 01110101 - 10000010 ;CALL LED6 = 130 - 143 10000010 - 10001111 ;CALL LED6A = 143 - 156 10001111 - 10011100 ;CALL LED7 = 156 - 169 10011100 - 10101001 ;CALL LED7A = 169 - 182 10101001 - 10110110 ;CALL LED8 = 182 - 195 10110110 - 11000011 ;CALL LED8A = 195 - 208 11000011 - 11010000 ;CALL LED9 = 208 - 221 11010000 - 11011101 ;CALL LED9A = 221 - 234 11011101 - 11101010 ;CALL LED10 = 234 - 245 11101010 - 11110101 ;CALL LED10A = 245 - 255 11110101 - 11111111 ; ;====================================================